﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PalFramework.Manager;
using PalBattleEmulator.Graphic;
using PalBattleEmulator.Battle;
using PalBattleEmulator.Command;
using System.Threading;

namespace PalBattleEmulator.Manager
{
    public class GameClockManager : IGameClockManager
    {
        private GameGraphicManager graphicControl;          //图形绘制控件

        //TODO::场景
        private GameBattle battle;                      //进行中的战斗

        public GameBattle Battle
        {
            get { return battle; }
        }

        private Thread mainThread;                      //游戏主线程

        private Queue<GameCommand> commandQueue;
        private Queue<GameCommand> todispatchCommands;

        public GameGraphicManager GraphicControl
        {
            get
            {
                return graphicControl;
            }
            set
            {
                graphicControl = value;
            }
        }

        #region IManager 成员

        public void Initialize()
        {
            commandQueue = new Queue<GameCommand>();
            todispatchCommands = new Queue<GameCommand>();
            //battle = new GameBattle();
            //battle.Initialize();
            //layers = new List<IGraphicLayer>();

            //BattleFieldLayer battleFieldLayer = new BattleFieldLayer();
            //battleFieldLayer.BattleField = 1;
            //layers.Add(battleFieldLayer);

            //UnitLayer unitLayer = new UnitLayer();
            //CharacterGraphic char1 = new CharacterGraphic(180, 120, 1);
            //char1.SetFrames(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, true);
            //CharacterGraphic char2 = new CharacterGraphic(240, 120, 2);
            //char2.SetFrames(new int[] { 1 }, false);
            //unitLayer.setUnit(new UnitGraphic[] { char1, char2 });
            //layers.Add(unitLayer);
        }

        

        public void Launch()
        {
            if (mainThread == null || !mainThread.IsAlive)
            {
                mainThread = new Thread(new ThreadStart(run));
                mainThread.IsBackground = true;
                mainThread.Start();
            }
        }

        public void Stop()
        {
            if (mainThread != null)
            {
                mainThread.Abort();
                mainThread = null;
            }
        }

        #endregion

        private bool battleStart;

        public void BattleStart()
        {
            battleStart = true;
        }

        /// <summary>
        /// 主循环
        /// </summary>
        private void run()
        {
            while (true)
            {
                if (battleStart)
                {
                    battleStart = false;
                    battle = BattleFactory.CreateTestBattle();
                    ContextModules.BattleManager.StartBattle(battle);
                }


                Sleep(GlobalConfig.GAME_CLOCK_SPAN);

                //战斗
                if (battle != null)
                {
                }
            }
        }

        public void Sleep(int millis)
        {
            Thread.Sleep(millis);
            //处理sleep期间的用户操作
            dispatchCommands();
        }

        public void OnCommand(GameCommand command)
        {
            Monitor.Enter(commandQueue);
            commandQueue.Enqueue(command);
            Monitor.Exit(commandQueue);
        }

        

        private void dispatchCommands()
        {
            Monitor.Enter(commandQueue);
            while (commandQueue.Count > 0)
                todispatchCommands.Enqueue(commandQueue.Dequeue());
            Monitor.Exit(commandQueue);

            //dispatch
            while (todispatchCommands.Count > 0)
            {
                handleCommand(todispatchCommands.Dequeue());
            }
        }

        private void handleCommand(GameCommand command)
        {
            switch (command.Type)
            {
                case CommandTypes.INPUT_KEYBOARD_DOWN:
                    {
                        KeyboardInputCommand cmd = (KeyboardInputCommand)command;
                        if (cmd.KeyEvent.Key == System.Windows.Input.Key.D1 && cmd.KeyEvent.IsDown)
                        {
                            if (battle == null) return;
                            AttackGraphicCommand grpcommand = new AttackGraphicCommand(CommandTypes.GRAPHIC_ATTACK_BEGIN);
                            grpcommand.PosX = battle.EnemyTeam.Units[0].Array.PosX;
                            grpcommand.PosY = battle.EnemyTeam.Units[0].Array.PosY;
                            ContextModules.GraphicControl.unitLayer.Characters[0].OnCommand(grpcommand);
                        }
                        else if (cmd.KeyEvent.Key == System.Windows.Input.Key.D2 && cmd.KeyEvent.IsDown)
                        {
                            if (battle == null) return;
                            int posX = battle.EnemyTeam.Units[0].Array.PosX;
                            int posY = battle.EnemyTeam.Units[0].Array.PosY;
                            ContextModules.GraphicControl.unitLayer.PlayEffect(0, posX, posY);
                        }
                    }
                    break;
            }
        }

        private static int pixelsize = GlobalConfig.GRAPHIC_WIDTH * GlobalConfig.GRAPHIC_HEIGHT * GlobalConfig.GRAPHIC_BYTES_PER_PIXEL;
        private byte[] createEmptyPixels()
        {
            return new byte[pixelsize];
        }
    }
}
